package com.yangm.utils;

/**
 * @program: MavenTest
 * @description:
 * @author: yang
 * @version: 1.0
 * @create: 2020/12/24 19:28
 **/

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @program:
 * @description: 文件工具类
 * @author: yang
 * @version: 1.0
 * @create: 2020/7/16 15:35
 **/
public class FileUtils {

    /***
     * @description: 创建目录集合
     * @param: path
    folderNames
     * @return: void
     * @author: ym
     * @date: 2021/1/24 22:29
     */
    public static void createDirectorys(String path,String[] folderNames){
        for (String name : folderNames) {
            File file = new File(path + File.separator + name);
            if(!file.exists()){
                file.mkdirs();
            }
        }
    }


    /*************************删除文件夹delFolder / 删除文件夹中的所有文件delAllFile *start***********/

    /***
     * @description: 删除文件夹内指定后缀的文件
     * @param: path
    suffix
     * @return: void
     * @author: ym
     * @date: 2020/11/26 11:41
     */
    public static void delFileBySuffix(String path,String suffix){
        System.out.println("path = " + path);
        File file = new File(path);
        if(!file.isDirectory()){
            System.out.println("路径错误!");
            return;
        }
        File[] files = file.listFiles();
        for (File f : files) {
            if(f.isDirectory()){
                delFileBySuffix(f.getPath(),suffix);
            }else if(f.isFile()){
                if(getFileSuffix(f.getName()).equals(suffix)){
                    System.out.println("删除：" + f.getName());
                    f.delete();
                }
            }
        }

    }
    /**
     * 获取指定文件或文件夹的后缀名
     * @param fileName  文件名称
     * @return
     */
    public static String getFileSuffix(String fileName){
        return fileName.substring(fileName.lastIndexOf(".") + 1);//例如：abc.png  截取后：png
    }

    /**
     * 删除文件夹
     * @param folderPath 文件夹完整绝对路径 ,"Z:/xuyun/save"
     */
    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); //删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); //删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除指定文件夹下所有文件
     * @param path 文件夹完整绝对路径 ,"Z:/xuyun/save"
     */
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);//再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    /***
     * @description: 删除一个文件
     * @param: fliePath
     * @return: boolean
     * @author: ym
     * @date: 2020/12/21 9:19
     */
    public static boolean deleteFile(String fliePath){
        return new File(fliePath).delete();
    }

    /**************删除文件夹delFolder / 删除文件夹中的所有文件delAllFile *over*******/

    /***
     * @description: 删除目录下的指定文件集合
     * @param: filePath
    		   deleteTypes
     * @return: void
     * @author: ym
     * @date: 2021/9/26 17:35
     */
    public static void deleteFile(String filePath,String[] deleteTypes) {
        File file = new File(filePath);
        if(!(file.exists() && file.isDirectory() && deleteTypes.length > 0)){
            return;
        }
        File[] files = file.listFiles();
        for (File f : files) {
            for (String deleteType : deleteTypes) {
                if(f.getName().indexOf(deleteType) > -1){
                    System.out.println(f.getName());
                    f.delete();
                    break;
                }
            }
        }
    }


    /***
     * @description: 替换文件的文本内容
     * @param: path
    		   regex
    		   replacement
     * @return: void
     * @author: ym
     * @date: 2021/9/26 17:37
     */
    public static void replace(String path,String regex, String replacement){
        File file = new File(path);
        try (FileInputStream fis = new FileInputStream(file);
             InputStreamReader isr = new InputStreamReader(fis);
             BufferedReader br = new BufferedReader(isr)){
            // 保存该行前面的内容
            StringBuffer buf = new StringBuffer();
            String temp = "";
            while ((temp = br.readLine()) != null){
                System.out.println(temp);
                temp = temp.replaceAll(regex,replacement);
                buf = buf.append(temp);
                // 换行
                buf = buf.append(System.getProperty("line.separator"));
            }
            try (FileOutputStream fos = new FileOutputStream(file);){
                PrintWriter pw = new PrintWriter(fos);
                pw.write(buf.toString().toCharArray());
                pw.flush();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /***
     * @description: 文件内容替换 思路：先将文件夹读取出来，用一个对象保存，对比不同就替换，然后覆盖文件内容
     * @param: path
    		   oldStr
    		   replaceStr
     * @return: void
     * @author: ym
     * @date: 2021/9/26 17:40
     */
    public static void replaceTxtByStr(String path,String oldStr,String replaceStr) throws IOException {
        File file = new File(path);
        try (FileInputStream fis = new FileInputStream(file);
             InputStreamReader isr = new InputStreamReader(fis);
             BufferedReader br = new BufferedReader(isr);){
            // 保存该行前面的内容
            StringBuffer buf = new StringBuffer();
            String temp = "";
            while ((temp = br.readLine()) != null){
                System.out.println(temp);
                if(temp.equals(oldStr)){
                    buf = buf.append(replaceStr);
                }else {
                    buf = buf.append(temp);
                }
                // 换行
                buf = buf.append(System.getProperty("line.separator"));
            }
            try (FileOutputStream fos = new FileOutputStream(file);){
                PrintWriter pw = new PrintWriter(fos);
                pw.write(buf.toString().toCharArray());
                pw.flush();

            }
        }
    }

    /**
     * @description: 文件重命名
     * @param: path
    oldname
    newname
     * @return: void
     * @author: ym
     * @date: 2020/7/16 15:48
     */
    public static void renameFile(String path,String oldname,String newname){
        if(!oldname.equals(newname)){//新的文件名和以前文件名不同时,才有必要进行重命名
            File newfile=new File(path+"/"+newname);
            if(newfile.exists()){
                //若在该目录下已经有一个文件和新文件名相同，则不允许重命名
                System.out.println(newname+"已经存在！");
            } else{
                new File(path+"/"+oldname).renameTo(newfile);
            }
        }
    }

    /**
     * @description: 创建文件
     * @param: filePath
     * @return: boolean
     * @author: ym
     * @date: 2020/7/16 15:45
     */
    public boolean createNewFile(String filePath) throws IOException {
        File file = new File(filePath);
        if(file.exists() && file.isDirectory()){
            return true;
        }
        return file.createNewFile(); // 创建新文件
    }

    /**
     * @description: 写入文件
     * @param: filePath
    stringList
     * @return: void
     * @author: ym
     * @date: 2020/7/16 15:44
     */
    public void writeFile(String filePath, List<String> stringList) {
        try (BufferedWriter out = new BufferedWriter(new FileWriter(filePath,true));){
            for (String s : stringList) {
                out.write(s);
            }
            out.flush(); // 清空缓冲区
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void writeFile(File file, List<String> stringList) {
        try (BufferedWriter out = new BufferedWriter(new FileWriter(file,true));){
            for (String s : stringList) {
                out.write(s);
            }
            out.flush(); // 清空缓冲区
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @description: 读取文件
     * @param: filePath
     * @return: void
     * @author: ym
     * @date: 2020/7/16 15:44
     */
    public static List<String> readFile(String filePath, String charsetName) throws IOException{
        return readFile(new File(filePath),charsetName);
    }



    public static List<String> readFile(File filePath, String charsetName) throws IOException{
        List<String> list = new ArrayList<>();
        /*try (FileReader reader = new FileReader(file);
             BufferedReader br = new BufferedReader(reader) // 建立一个对象，它把文件内容转成计算机能读懂的语言
        )*/
        try(FileInputStream fileInputStream = new FileInputStream(filePath);
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,charsetName);
            BufferedReader br = new BufferedReader(inputStreamReader)
        ){
            String line;
            while ((line = br.readLine()) != null) {
                list.add(line);
            }
        }
        return list;
    }

    /***
     * @description: 写入文件(用缓存)
     * @param: filePath
    		   txtName
    		   strings
     * @return: java.io.File
     * @author: ym
     * @date: 2021/1/14 10:52
     */
    public static File writeFile(String filePath,String txtName, String[] strings) throws IOException{
        File file1 = new File(filePath);
        if(!file1.exists()){
            file1.mkdirs();
        }
        File file2 = new File(filePath + txtName);
        if(!file2.exists()){
            file2.createNewFile();
        }

//		try (BufferedWriter out = new BufferedWriter(new FileWriter(file2,true),1024);){
        try (FileOutputStream fileOutputStream = new FileOutputStream(file2);
             OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"utf-8");
             BufferedWriter out = new BufferedWriter(outputStreamWriter,1024);){
            int i = 0;
            for (String s : strings) {
                if(i == 0){
                    out.write(s);
                }else {
                    out.write("\n" + s);
                }
                i++;
            }
            out.flush(); // 清空缓冲区
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return file2;
    }

    /***
     * @description: 根据文件路径集合字符串删除文件信息
     * @param: fileUrls 路径集合字符串
               pathPrefix 路径前缀
    		   delimiter 分隔符
     * @return: void
     * @author: ym
     * @date: 2021/9/26 17:47
     */
    public static void deleteFileByUrls(String fileUrls,String pathPrefix,String delimiter){
        if(StrUtil.isBlank(fileUrls)){
            return;
        }
        String[] fileUrlsArray = fileUrls.split(delimiter);
        if(fileUrlsArray.length == 0){
            return;
        }
        for (String s : fileUrlsArray) {
            File file = new File(pathPrefix + s);
            if (file.exists()){
                file.delete();
            }
        }
    }

    /***
     * @description: 删除Map集合里面的数据文件
     * @param: mapList
    		   rootPath
    		   delimiter
     * @return: void
     * @author: ym
     * @date: 2021/9/26 17:49
     */
    private static void deleteDataFile(List<Map<String, Object>> mapList, String rootPath, String delimiter) {
        for (Map<String, Object> map : mapList) {
            for (String s : map.keySet()) {
                if(map.get(s) != null){
                    String path = map.get(s).toString();
                    if (!StrUtil.isBlank(path)){
                        // 判断是否存在多个路径
                        if(path.endsWith(delimiter)){
                            deleteFileByUrls(path, rootPath,delimiter);
                        }else {
                            File file = new File(rootPath + path);
                            if (file.exists()){
                                file.delete();
                            }
                        }
                    }
                }
            }
        }
    }

    /***
     * @description: 根据url下载数据
     * @param: url
    		   outFile
     * @return: void
     * @author: ym
     * @date: 22/1/14 9:43
     */
    public static void urlToData(String url,String outFile) throws IOException{
        URL target = new URL(url);
        URLConnection urlConnection = target.openConnection();
        try(InputStream inputStream = urlConnection.getInputStream();
            FileOutputStream fileOutputStream = new FileOutputStream(outFile)){
            IoUtil.copy(inputStream,fileOutputStream,1024);
        }
    }

    /***
     * @description: 下载数据
     * @param: jsonData
               outPath
     * @return: java.lang.String
     * @author: ym
     * @date: 22/1/14 11:19
     */
    public static String downloadUrlData(String jsonData,String outPath) throws IOException {
        if(StrUtil.hasEmpty(jsonData,outPath)){
            return null;
        }
        if(!new File(outPath).exists()){
            new File(outPath).mkdirs();
        }
        StringBuffer path = new StringBuffer();
        JSONArray jsonArray = JSONArray.parseArray(jsonData);
        for (Object o : jsonArray) {
            JSONObject jsonObject = (JSONObject) o;
            String fileName = jsonObject.getString("FILE_NAME");
            String fileUrl = jsonObject.getString("FILE_URL");
            String outFileName = outPath + File.separator + fileName;
            ThreadUtil.execute(()->{
                try {
                    urlToData(fileUrl,outFileName);
                } catch (IOException e) {
                    System.out.println(String.format("下载异常：{名称：%s}{地址：%s}",outFileName,fileUrl));
                }
            });
            urlToData(fileUrl,outFileName);
            path.append(outFileName).append(";");
        }
        return path.toString();
    }

}
